package fr.upmc.i3s.upmcontact.views.fragments;

import java.util.List;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TableLayout;
import android.widget.TextView;
import fr.upmc.i3s.upmcontact.R;
import fr.upmc.i3s.upmcontact.backend.BackEndBridgeImpl;
import fr.upmc.i3s.upmcontact.callbacks.ICollectAllCallback;
import fr.upmc.i3s.upmcontact.content.collectors.CollectorsController;
import fr.upmc.i3s.upmcontact.content.collectors.UpdateDatesManager;
import fr.upmc.i3s.upmcontact.content.containers.CollectedContentManager;
import fr.upmc.i3s.upmcontact.contents.LostFoundObject;
import fr.upmc.i3s.upmcontact.contents.MerchantInfo;
import fr.upmc.i3s.upmcontact.contents.Published;
import fr.upmc.i3s.upmcontact.contents.StudentLifeInfo;
import fr.upmc.i3s.upmcontact.contents.UpmcInfo;
import fr.upmc.i3s.upmcontact.librairies.pulltorefresh.PullToRefreshBase;
import fr.upmc.i3s.upmcontact.librairies.pulltorefresh.PullToRefreshBase.OnRefreshListener;
import fr.upmc.i3s.upmcontact.librairies.pulltorefresh.PullToRefreshScrollView;
import fr.upmc.i3s.upmcontact.tools.BitmapFactoryAdapter;
import fr.upmc.i3s.upmcontact.tools.DateUtils;
import fr.upmc.i3s.upmcontact.tools.RandomUtils;
import fr.upmc.i3s.upmcontact.tools.StringUtils;
import fr.upmc.i3s.upmcontact.views.FragmentController;
import fr.upmc.i3s.upmcontact.views.fragments.models.IFragmentModel;
import fr.upmc.i3s.upmcontact.views.fragments.models.PageFragmentModel;

public class HomeFragment extends PageFragmentModel implements IFragmentModel {
	
	private static final String TAG = "HomeFragment";
	
	private FragmentController fragmentController;
	private static volatile HomeFragment INSTANCE;
	
	private PullToRefreshScrollView prsvContent;
	private ImageView ivRandHome;
	private TextView tvWelcome;
	private TableLayout tlRecentNews;
	private TableLayout tlLastLost;
	private TableLayout tlLastFound;
	private TextView tvFeetLeft;
	private TextView tvFeetRight;
	private ImageView ivArrowLeft;
	private ImageView ivArrowRight;
	
	public static HomeFragment getInstance() {
		if(INSTANCE == null) {
			HomeFragment fragment = new HomeFragment();
		    Bundle bundle = new Bundle(3);
		    bundle.putInt(EXTRA_LAYOUT_FRAGMENT, R.layout.fragment_home);
		    bundle.putInt(EXTRA_HEAD_ICON, R.drawable.ic_menu_home_white);
		    bundle.putInt(EXTRA_HEAD_TEXT, R.string.title_fragment_home);
		    fragment.setArguments(bundle);
		    INSTANCE = fragment;
		}
	    return INSTANCE;
	}
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		return super.onCreateView(inflater, container, savedInstanceState);
	}
	
 	@Override
	public void onViewCreated(View view, Bundle savedInstanceState) {
		super.initFragmentViews();
		this.fragmentController = (FragmentController) getActivity();
		fetchViews();
		customizeViews();
		setListeners();
	}
 	
 	@Override
 	public void fetchViews() {
 		this.prsvContent = (PullToRefreshScrollView) this.getView().findViewById(R.id.pullToRefreshScrollview_content);
 		this.ivRandHome = (ImageView) this.getView().findViewById(R.id.imageView_randHome);
 		this.tvWelcome = (TextView) this.getView().findViewById(R.id.textView_welcome);
 		this.tlRecentNews = (TableLayout) this.getView().findViewById(R.id.tableLayout_recent_news);
 		this.tlLastLost = (TableLayout) this.getView().findViewById(R.id.tableLayout_last_lost);
 		this.tlLastFound = (TableLayout) this.getView().findViewById(R.id.tableLayout_last_found);
 		this.tvFeetLeft = (TextView) this.getView().findViewById(R.id.textView_feet_text_left);
 		this.tvFeetRight = (TextView) this.getView().findViewById(R.id.textView_feet_text_right);
 		this.ivArrowLeft = (ImageView) this.getView().findViewById(R.id.imageView_feet_arrow_left);
 		this.ivArrowRight = (ImageView) this.getView().findViewById(R.id.imageView_feet_arrow_right);
 	}
 	
 	@Override
 	public void customizeViews() {
 		this.tvFeetLeft.setText("");
 		this.tvFeetRight.setText("");
 		this.ivArrowLeft.setVisibility(View.GONE);
 		this.ivArrowRight.setVisibility(View.GONE);
 		if(BackEndBridgeImpl.getInstance(fragmentController).getCurrentUser() != null) {
 	 		this.tvWelcome.setText(fragmentController.getString(R.string.welcome_msg)+", "+
						StringUtils.toProperNoun(BackEndBridgeImpl.getInstance(fragmentController).getCurrentUser().getUsername()+" !"));
 		} else {
 	 		this.tvWelcome.setText(fragmentController.getString(R.string.welcome_msg)+" !");
 		}
 		this.ivRandHome.setImageDrawable(fragmentController.getResources().getDrawable(RandomUtils.getRandomIdDrawable()));
 		updateRecentContent();
 	}
 	
 	@Override
 	public void setListeners() {
 		this.prsvContent.setOnRefreshListener(onContentRefreshListener);
 	}
 	
 	public void updateRecentContent() {
 		LayoutInflater inflater = (LayoutInflater) fragmentController.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 		// fill recent news :
 		fillRecentNews(inflater);
 		// fill last lost :
 		fillLastLostObjects(inflater);
 		// fill last found :
 		fillLastFoundObjects(inflater);
 		// set last update date for pull to refresh :
 		updateDate();
 	}
 	
	private void updateDate() {
 		this.prsvContent.getLoadingLayoutProxy().setLastUpdatedLabel(
 				fragmentController.getString(R.string.pull_to_refresh_last_update)+" "+
 				DateUtils.toDisplayDateTime(UpdateDatesManager.retrieveUpdateGlobalDate(fragmentController)));
	}
 	
 	private void fillRecentNews(LayoutInflater inflater) {
 		// get random recent new
 		final Published info = CollectedContentManager.getInstance(fragmentController).getRandomRecentInformation();
 		if(info != null) {
 	 		this.tlRecentNews.removeAllViews();
 	 		View row = inflater.inflate(R.layout.layout_row_recent_news, null);
 	 		// fetch views
 	 		ImageView ivPhoto = (ImageView) row.findViewById(R.id.imageView_photo);
 	 		TextView tvTitle = (TextView) row.findViewById(R.id.textView_title);
 	 		TextView tvDescription = (TextView) row.findViewById(R.id.textView_description);
 	 		TextView tvDate = (TextView) row.findViewById(R.id.textView_published_at);
 	 		TextView tvMore = (TextView) row.findViewById(R.id.textView_more);
 	 		// custom views
 	 		if(info.getPhotoPath() != null) {
 	 			Bitmap bm = BitmapFactoryAdapter.decodeFile(info.getPhotoPath(), 250);
 	 			ivPhoto.setImageBitmap(bm);
 	 		} else {
 	 			if(info instanceof UpmcInfo) {
 	 				ivPhoto.setImageResource(R.drawable.ph_info_point);
 	 			} else if (info instanceof MerchantInfo) {
 	 				ivPhoto.setImageResource(R.drawable.ph_merchants);
 	 			} else if (info instanceof StudentLifeInfo) {
 	 				ivPhoto.setImageResource(R.drawable.ph_logo_bde);
 	 			}
 	 		}
 	 		tvTitle.setText(info.getTitle());
 	 		tvDescription.setText(info.getDescription());
 	 		tvDate.setText(DateUtils.toDisplayDateTime(info.getCreatedAt()));
 	 		// set listeners
 	 		tvMore.setOnClickListener(new OnClickListener() {
 				@Override
 				public void onClick(View arg0) {
 					Fragment frag;
 					if(info instanceof UpmcInfo) {
 		 				frag = FeedUpmcInfosFragment.getInstance();
 		 			} else if (info instanceof MerchantInfo) {
 		 				frag = FeedMerchantsInfosFragment.getInstance();
 		 			} else if (info instanceof StudentLifeInfo) {
 		 				frag = FeedStudentInfosFragment.getInstance();
 		 			} else {
 		 				frag = HomeFragment.getInstance();
 		 			}
 		 			fragmentController.switchContent(frag, FragmentController.TRANSACTION_FROM_RIGHT_TO_LEFT);
 				}
 	 		});
 	 		// change IDs
 	 		int randId = (int) Math.round(Math.random()*1000);
 	 		row.setId(row.getId()+randId);
 	 		tvTitle.setId(tvTitle.getId()+randId);
 	 		tvDescription.setId(tvDescription.getId()+randId);
 	 		tvDate.setId(tvDate.getId()+randId);
 	 		ivPhoto.setId(ivPhoto.getId()+randId);
 	 		tvMore.setId(tvMore.getId()+randId);
 	 		this.tlRecentNews.addView(row);
 		}
 	}
 	
 	private void fillLastLostObjects(LayoutInflater inflater) {
 		// get the 4 more recent lost objects
 		List<LostFoundObject> list = CollectedContentManager.getInstance(fragmentController).getRecentLostObjects(4);
 		if(list != null && list.size() > 0) {
 	 		this.tlLastLost.removeAllViews();
 	 		View row = inflater.inflate(R.layout.layout_row_last_objects, null);
 	 		// fetch views
 	 		LinearLayout llCells = (LinearLayout) row.findViewById(R.id.linearLayout_cells_objects);
 	 		TextView tvMore = (TextView) row.findViewById(R.id.textView_more);
 	 		// inflate cell for each object 
 	 		for(LostFoundObject lfo : list) {
 	 			View cell = inflater.inflate(R.layout.layout_cell_object, null);
 	 			// fetch views
 	 	 		ImageView ivPhoto = (ImageView) cell.findViewById(R.id.imageView_photo);
 	 	 		TextView tvTitle = (TextView) cell.findViewById(R.id.textView_title);
 	 	 		// custom views
 	 	 		if(lfo.getPhotoPath() != null) {
 	 	 			Bitmap bm = BitmapFactoryAdapter.decodeFile(lfo.getPhotoPath(), 250);
 	 	 			ivPhoto.setImageBitmap(bm);
 	 	 		} else {
 	 	 			ivPhoto.setImageResource(R.drawable.ph_lost);
 	 	 		}
 	 	 		tvTitle.setText(lfo.getName());
 	 	 		// change IDs
 	 	 		int randId = (int) Math.round(Math.random()*1000);
 	 	 		row.setId(row.getId()+randId);
 	 	 		tvTitle.setId(tvTitle.getId()+randId);
 	 	 		ivPhoto.setId(ivPhoto.getId()+randId);
 	 	 		// add to container
 	 	 		llCells.addView(cell);
 	 		}
 	 		// set listeners
 	 		tvMore.setOnClickListener(new OnClickListener() {
 				@Override
 				public void onClick(View arg0) {
 		 			fragmentController.switchContent(FeedLostObjectsFragment.getInstance(),
 		 									FragmentController.TRANSACTION_FROM_RIGHT_TO_LEFT);
 				}
 	 		});
 	 		// change IDs
 	 		int randId = (int) Math.round(Math.random()*1000);
 	 		row.setId(row.getId()+randId);
 	 		tvMore.setId(tvMore.getId()+randId);
 	 		this.tlLastLost.addView(row);
 		}
 	}
 	
 	
 	private void fillLastFoundObjects(LayoutInflater inflater) {
 		// get the 4 more recent lost objects
 		List<LostFoundObject> list = CollectedContentManager.getInstance(fragmentController).getRecentFoundObjects(4);
 		if(list != null && list.size() > 0) {
 	 		this.tlLastFound.removeAllViews();
 	 		View row = inflater.inflate(R.layout.layout_row_last_objects, null);
 	 		// fetch views
 	 		LinearLayout llCells = (LinearLayout) row.findViewById(R.id.linearLayout_cells_objects);
 	 		TextView tvMore = (TextView) row.findViewById(R.id.textView_more);
 	 		// inflate cell for each object 
 	 		for(LostFoundObject lfo : list) {
 	 			View cell = inflater.inflate(R.layout.layout_cell_object, null);
 	 			// fetch views
 	 	 		ImageView ivPhoto = (ImageView) cell.findViewById(R.id.imageView_photo);
 	 	 		TextView tvTitle = (TextView) cell.findViewById(R.id.textView_title);
 	 	 		// custom views
 	 	 		if(lfo.getPhotoPath() != null) {
 	 	 			Bitmap bm = BitmapFactoryAdapter.decodeFile(lfo.getPhotoPath(), 250);
 	 	 			ivPhoto.setImageBitmap(bm);
 	 	 		} else {
 	 	 			ivPhoto.setImageResource(R.drawable.ph_lost);
 	 	 		}
 	 	 		tvTitle.setText(lfo.getName());
 	 	 		// change IDs
 	 	 		int randId = (int) Math.round(Math.random()*1000);
 	 	 		row.setId(row.getId()+randId);
 	 	 		tvTitle.setId(tvTitle.getId()+randId);
 	 	 		ivPhoto.setId(ivPhoto.getId()+randId);
 	 	 		// add to container
 	 	 		llCells.addView(cell);
 	 		}
 	 		// set listeners
 	 		tvMore.setOnClickListener(new OnClickListener() {
 				@Override
 				public void onClick(View arg0) {
 		 			fragmentController.switchContent(FeedFoundObjectsFragment.getInstance(),
 		 									FragmentController.TRANSACTION_FROM_RIGHT_TO_LEFT);
 				}
 	 		});
 	 		// change IDs
 	 		int randId = (int) Math.round(Math.random()*1000);
 	 		row.setId(row.getId()+randId);
 	 		tvMore.setId(tvMore.getId()+randId);
 	 		this.tlLastFound.addView(row);
 		}
 	}
 	
 	
	  //////////////
	 // CALLBACK //
	//////////////
	
	private ICollectAllCallback collectAllCallback = new ICollectAllCallback() {
		@Override
		public void collectEnded() {
			prsvContent.onRefreshComplete();
			updateDate();
			LayoutInflater inflater = (LayoutInflater) fragmentController.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	 		fillRecentNews(inflater);
	 		fillLastLostObjects(inflater);
	 		fillLastFoundObjects(inflater);
		}
	};
 	
 	
	  ///////////////
	 // LISTENERS //
	///////////////
	
	private OnRefreshListener<ScrollView> onContentRefreshListener = new OnRefreshListener<ScrollView>() {
		@Override
		public void onRefresh(PullToRefreshBase<ScrollView> refreshView) {
			Log.i(TAG, "onContentRefreshListener.onRefresh");
			CollectorsController.getInstance(fragmentController)
			.collectAll(fragmentController, collectAllCallback);
		}
	};
	
}